package icraf.carbon.gui;

import icraf.carbon.core.Project;
import icraf.carbon.core.ProjectIO;
import icraf.carbon.core.Zone.DataType;
import icraf.carbon.gui.LCTableModel.DisplayType;
import icraf.carbon.gui.LCTableModel.FormType;
import icraf.carbon.gui.MenuFactory.MenuProperty;
import icraf.common.gui.MenuGenerator;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

public class MatrixFormPanel extends JPanel{
	private class Listener extends MouseAdapter implements ActionListener, TableModelListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			if(e.getSource().equals(typeCB)){
				if(typeCB.getSelectedIndex() == 0) {
					typeList.setText(types[1]+":");
					tableModel.setFormType(FormType.FROM_LC_TO_LIST);
				} else if(typeCB.getSelectedIndex() == 1) {
					typeList.setText(types[0]+":");
					tableModel.setFormType(FormType.TO_LC_FROM_LIST);
				}
			} else if(e.getSource().equals(lcListCB)){
				tableModel.setLandcoverBaseIndex(lcListCB.getSelectedIndex());
			} else if (MenuProperty.GENERAL_VIEW_MATRIX.isAction(e)) {
				if(mainPanel != null) {
					tableModel.setDisplayType(DisplayType.MATRIX_VIEW);
					mainPanel.unitCB.setSelectedIndex(tableModel.isAreaScale()?1:0);
					mainPanel.showMatrixView();
				}
			} else if (e.getSource().equals(unitCB)) {
				updateUnit();
			}
			
		}

		@Override
		public void tableChanged(TableModelEvent e) {
			if(e.getType() == TableModelEvent.UPDATE) {
				if(mainPanel != null)
					totalLabel.setText(mainPanel.formatValue(tableModel.getValueTotal()));
			}
			
		}
		
		@Override
		public void mouseReleased(MouseEvent e) {
			if (e.isPopupTrigger()||e.isControlDown()||e.getButton()==MouseEvent.BUTTON3) {
				if (e.getSource().equals(controlPanel)) {
					popMenu.show((Component) e.getSource(), e.getX(), e.getY());
				} 
			}
			
		}

	}
	
	private class LandCoverListModel extends AbstractListModel implements ComboBoxModel {
		private static final long serialVersionUID = -6357141301305147712L;
		private LCTableModel lcTableModel;
		private Object selection;
		
		public LandCoverListModel(LCTableModel lcTableModel) {
			super();
			this.lcTableModel = lcTableModel;
		}

		@Override
		public int getSize() {
			Project p = lcTableModel.getProject();
			if(p != null) {
				return p.getLandCoverList().size();
			}
			return 0;
		}

		@Override
		public Object getElementAt(int index) {
			Project p = lcTableModel.getProject();
			if(p != null) {
				return p.getLandCoverList().get(index);
			}
			return null;
		}

		@Override
		public void setSelectedItem(Object anItem) {
			selection = anItem;
		}

		@Override
		public Object getSelectedItem() {
			return selection;
		}
	}
	
	private static final long serialVersionUID = 6718619950714550718L;


	public static void main(String[] args) {
		Project p = null;
		try {

			p = ProjectIO
					.loadData(new FileReader(new File("c:/degi/Kaltim.car")));
		} catch (IOException e) {
			e.printStackTrace();
		}

		p.updateDataArray();
		LCTableModel mod = new LCTableModel();
		MatrixFormPanel m = new MatrixFormPanel(null, mod);
		mod.setProject(p);
		m.setDataType(DataType.LANDCOVER_CHANGE, null);
		m.updateDisplay();
		final JFrame frame = new JFrame();
		frame.getContentPane().add(m);
		frame.pack();
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				frame.setVisible(true);
			}
		});
	}
	
	private LCTableModel tableModel;
	private String[] types = {"FROM", "TO"};
	private JComboBox lcListCB;
	private JComboBox typeCB;
	private JLabel typeList = new JLabel();
	private Listener listener = new Listener();
	private MatrixPanel mainPanel;
	private JLabel totalLabel;
	
	private String unitArea = "";
	private JComboBox unitCB = new JComboBox();
	private String unitDefault = "";
	private JLabel unitLabel = new JLabel();
	private DefaultComboBoxModel unitModelCB = new DefaultComboBoxModel();
	private JPanel unitCornerPanel;
	private MatrixPanel lcListTable;
	private JPopupMenu popMenu = new JPopupMenu();
	private JToolBar controlPanel;
	
	public MatrixFormPanel(MatrixPanel mainPanel, LCTableModel tableModel) {
		this.mainPanel = mainPanel;
		this.tableModel = tableModel;
		lcListTable = new MatrixPanel(tableModel, false, false,
				false, false, true);
		tableModel.addTableModelListener(listener);
		typeCB = new JComboBox(types);
		typeCB.addActionListener(listener );
		typeList.setText(types[1]+":");
		Font f = typeList.getFont().deriveFont(Font.BOLD);
		typeList.setFont(f);
		typeCB.setFont(f);
		typeList.setForeground(Color.red);
		typeCB.setForeground(Color.red);
		lcListCB = new JComboBox(new LandCoverListModel(tableModel));
		lcListCB.addActionListener(listener);
		lcListCB.setFont(f);
		
		JButton b = MenuFactory.createButtonIcon(MenuProperty.GENERAL_VIEW_MATRIX, listener);
		controlPanel = new JToolBar(); 
		controlPanel.setFloatable(false);
		controlPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 2));
		controlPanel.add(b);
		controlPanel.addSeparator();
		controlPanel.add(typeCB);
		controlPanel.add(lcListCB);
		controlPanel.add(typeList);
		
		unitCornerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
		JLabel l1 = new JLabel("Unit:");
		unitCornerPanel.add(l1);
		unitLabel.setText(unitDefault);
		unitCornerPanel.add(unitLabel);
		
		unitModelCB.addElement(unitDefault);
		unitModelCB.addElement(unitArea);
		unitCB.setModel(unitModelCB);
		unitCB.addActionListener(listener);
		
		totalLabel = new JLabel();
		JPanel statusP = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 2));
		statusP.add(new JLabel("Total: "));
		statusP.add(totalLabel);
		statusP.add(unitCornerPanel);
		
		popMenu.add(MenuGenerator.createMenuItem(MenuProperty.GENERAL_VIEW_MATRIX,
				listener));
		controlPanel.addMouseListener(listener);
		this.setLayout(new BorderLayout());
		this.add(lcListTable);
		this.add(controlPanel, BorderLayout.NORTH);
		this.add(statusP, BorderLayout.SOUTH);
	}


	public void setDataType(DataType dataType, Object attributes) {
		tableModel.setDataType(dataType, attributes);
	}

	public void setZoneIndex(int zoneIndex) {
		tableModel.setZoneIndex(zoneIndex);
	}


	public void updateDisplay() {
		tableModel.setDisplayType(DisplayType.FORM_VIEW);
		lcListCB.setSelectedIndex(tableModel.getLandcoverBaseIndex());
		unitCB.setSelectedIndex(tableModel.isAreaScale()?1:0);
		tableModel.getHighlightRows().clear();
		
	}
	
	private void updateUnit() {
		tableModel.setAreaScale(unitCB.getSelectedIndex() == 1, tableModel.isZoneArea());
		tableModel.fireTableDataChanged();

	}
	
	public void setUnit(String unitDefault, String unitArea) {
		this.unitDefault = unitDefault;
		this.unitArea = unitArea;
		unitLabel.setText(unitDefault);
		unitModelCB.removeAllElements();
		unitModelCB.addElement(unitDefault);
		unitModelCB.addElement(unitArea);
	}
	
	public void setUnitSelectable(boolean isUnitSelectable) {
		if (isUnitSelectable) {
			unitCornerPanel.remove(unitLabel);
			unitCornerPanel.add(unitCB);
		} else {
			unitCornerPanel.remove(unitCB);
			unitCornerPanel.add(unitLabel);
		}
	}


	public void setMenuDetail(boolean isMenuDetail, String menuDetailTitle) {
		lcListTable.setMenuDetail(isMenuDetail, menuDetailTitle);
	}
}
